// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;

namespace SnapObjects.Data
{
    internal abstract class SqlStatementParser : ISqlStatementParser
    {
        protected ISqlStatementFactory _factory;
        protected ISqlGenerationHelper _helper;
        protected int _bracket = 0;
        protected bool _isClause = false;

        public SqlStatementParser(ISqlStatementFactory factory, ISqlGenerationHelper helper)
        {
            _factory = factory;
            _helper = helper;
        }

        public abstract SqlStatement Parse(string sqlText);
        public abstract SqlStatement ParseStatement(ISqlTokenizer tokenizer, bool isClause);

        protected virtual SqlStatement ParseClause(ISqlTokenizer tokenizer, SqlClause clause)
        {
            if (tokenizer.Current.Text.Trim().Equals("select", StringComparison.OrdinalIgnoreCase))
            {
                var parser = (SqlStatementParser)_factory.GetSqlParser(SqlStatementType.Select);

                var statement = parser.ParseStatement(tokenizer, true);

                return statement;
            }
            else
            {
                throw new NotSupportedException(tokenizer.Current.Text);
            }
        }

        protected bool IsStatementBracketEnd(ISqlTokenizer tokenizer)
        {
            if (tokenizer.Current is SqlCharacterToken c)
            {
                if (c.Character == SqlCharacters.OpenParentheses)
                {
                    _bracket++;
                }
                else if (c.Character == SqlCharacters.CloseParentheses)
                {
                    _bracket--;

                    if (_bracket < 0 && _isClause)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}
